home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / arch / alpha / include / asm / percpu.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  2.2 KB  |  79 lines

  1. #ifndef __ALPHA_PERCPU_H
  2. #define __ALPHA_PERCPU_H
  3. #include <linux/compiler.h>
  4. #include <linux/threads.h>
  5.  
  6. /*
  7.  * Determine the real variable name from the name visible in the
  8.  * kernel sources.
  9.  */
  10. #define per_cpu_var(var) per_cpu__##var
  11.  
  12. #ifdef CONFIG_SMP
  13.  
  14. /*
  15.  * per_cpu_offset() is the offset that has to be added to a
  16.  * percpu variable to get to the instance for a certain processor.
  17.  */
  18. extern unsigned long __per_cpu_offset[NR_CPUS];
  19.  
  20. #define per_cpu_offset(x) (__per_cpu_offset[x])
  21.  
  22. #define __my_cpu_offset per_cpu_offset(raw_smp_processor_id())
  23. #ifdef CONFIG_DEBUG_PREEMPT
  24. #define my_cpu_offset per_cpu_offset(smp_processor_id())
  25. #else
  26. #define my_cpu_offset __my_cpu_offset
  27. #endif
  28.  
  29. #ifndef MODULE
  30. #define SHIFT_PERCPU_PTR(var, offset) RELOC_HIDE(&per_cpu_var(var), (offset))
  31. #define PER_CPU_ATTRIBUTES
  32. #else
  33. /*
  34.  * To calculate addresses of locally defined variables, GCC uses 32-bit
  35.  * displacement from the GP. Which doesn't work for per cpu variables in
  36.  * modules, as an offset to the kernel per cpu area is way above 4G.
  37.  *
  38.  * This forces allocation of a GOT entry for per cpu variable using
  39.  * ldq instruction with a 'literal' relocation.
  40.  */
  41. #define SHIFT_PERCPU_PTR(var, offset) ({        \
  42.     extern int simple_identifier_##var(void);    \
  43.     unsigned long __ptr, tmp_gp;            \
  44.     asm (  "br    %1, 1f                    \n\
  45.     1:    ldgp    %1, 0(%1)                  \n\
  46.         ldq %0, per_cpu__" #var"(%1)\t!literal"        \
  47.         : "=&r"(__ptr), "=&r"(tmp_gp));        \
  48.     (typeof(&per_cpu_var(var)))(__ptr + (offset)); })
  49.  
  50. #define PER_CPU_ATTRIBUTES    __used
  51.  
  52. #endif /* MODULE */
  53.  
  54. /*
  55.  * A percpu variable may point to a discarded regions. The following are
  56.  * established ways to produce a usable pointer from the percpu variable
  57.  * offset.
  58.  */
  59. #define per_cpu(var, cpu) \
  60.     (*SHIFT_PERCPU_PTR(var, per_cpu_offset(cpu)))
  61. #define __get_cpu_var(var) \
  62.     (*SHIFT_PERCPU_PTR(var, my_cpu_offset))
  63. #define __raw_get_cpu_var(var) \
  64.     (*SHIFT_PERCPU_PTR(var, __my_cpu_offset))
  65.  
  66. #else /* ! SMP */
  67.  
  68. #define per_cpu(var, cpu)        (*((void)(cpu), &per_cpu_var(var)))
  69. #define __get_cpu_var(var)        per_cpu_var(var)
  70. #define __raw_get_cpu_var(var)        per_cpu_var(var)
  71.  
  72. #define PER_CPU_ATTRIBUTES
  73.  
  74. #endif /* SMP */
  75.  
  76. #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu_var(name)
  77.  
  78. #endif /* __ALPHA_PERCPU_H */
  79.